/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cursoexperto.jftf.controller;

import java.math.BigDecimal;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import org.cursoexperto.jftf.controller.exceptions.NonexistentEntityException;
import org.cursoexperto.jftf.controller.exceptions.PreexistingEntityException;
import org.cursoexperto.jftf.entidades.Producto;

/**
 *
 * @author Jose Fernando
 */
public class ProductoJpaController {

    public ProductoJpaController() {
        emf = Persistence.createEntityManagerFactory("WebApplicationPU");
    }
    private EntityManagerFactory emf = null;

    /**
     * Devuelve el EntityManager
     * @return EntityManager.
     */
    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    /**
     * Encuentra todas los productos existentes.
     * @return Lista de productos.
     */
    public List<Producto> findProductoEntities() {
        EntityManager em = null;
        try {
            em = getEntityManager();
            Query q = em.createQuery("select object(o) from Producto as o");
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    /**
     * Devuelve el prodcuto para su identificador.
     * @param id identificador del prodcuto a buscar
     * @return Devuelve el prodcuto correspondiente a la busqueda o null
     */
    public Producto findProducto(Long id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Producto.class, id);
        } finally {
            em.close();
        }
    }

    /**
     * Devuelve la lista de productos de categoria
     * @param id identificador de la categoria
     * @return Devuelve la lista de prodcutos correspondiente a la busqueda o null
     */
    public List<Producto> findByCategoria(Long categoriaId) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createNamedQuery("Producto.findByCategoria").setParameter("idCategoria", categoriaId);
            return q.getResultList();
        } catch (NoResultException ex) {
            Logger.getLogger(ProductoJpaController.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        } catch (NonUniqueResultException ex) {
            Logger.getLogger(ProductoJpaController.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        } finally {
            em.close();
        }
    }

    /**
     * Encuentra todas los productos existentes.
     * @return Lista de productos.
     */
    public List<Producto> findAll() {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createNamedQuery("Producto.findAll");
            return q.getResultList();
        } catch (NoResultException ex) {
            Logger.getLogger(ProductoJpaController.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        } catch (NonUniqueResultException ex) {
            Logger.getLogger(ProductoJpaController.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        } finally {
            em.close();
        }
    }

    /**
     * Encuentra la lista de productos con los criterios de busqueda
     * @param p caracteristicas del producto
     *  @param precioInferior precio inferior de los criterios de busqueda
     *  @param precioSuperior precio superior de los criterios de busqueda
     * @return Lista de productos.
     */
    public List<Producto> findProductoEntitiesByQuery(Producto p, BigDecimal precioInferior, BigDecimal precioSuperior) {
        EntityManager em = getEntityManager();
        try {
            String stringAux = "select p from Producto p where 1 = 1 ";
            if (p.getProducto() != null && !p.getProducto().equals("")) {
                stringAux += " and upper(p.producto) like upper(:producto)";
            }
            if (p.getReferencia() != null && !p.getReferencia().equals("")) {
                stringAux += " and upper(p.referencia) like upper(:referencia)";
            }

            if (p.getDescripcion() != null && !p.getDescripcion().equals("")) {
                stringAux += " and upper(p.descripcion) like upper(:descripcion) ";
            }

            //Parametro de precio
            if (precioInferior.equals(BigDecimal.ZERO) && precioSuperior.equals(BigDecimal.ZERO)) {
            } else if (!precioInferior.equals(BigDecimal.ZERO) && !precioSuperior.equals(BigDecimal.ZERO)) {
                stringAux += " and p.precio BETWEEN :precioInferior AND :precioSuperior ";
            } else if (precioInferior.equals(BigDecimal.ZERO) && !precioSuperior.equals(BigDecimal.ZERO)) {
                stringAux += " and p.precio <= :precioSuperior ";
            } else if (!precioInferior.equals(BigDecimal.ZERO) && precioSuperior.equals(BigDecimal.ZERO)) {
                stringAux += " and p.precio >= :precioInferior ";
            }

            if (p.getIdCategoria() != null) {
                stringAux += " and p.idCategoria = :idCategoria ";
            }

            //Generacion de la query
            Query q = em.createQuery(stringAux);

            if (p.getProducto() != null && !p.getProducto().equals("")) {
                q.setParameter("producto", "%" + p.getProducto() + "%");
            }
            if (p.getReferencia() != null && !p.getReferencia().equals("")) {
                q.setParameter("referencia", "%" + p.getReferencia() + "%");
            }
            if (p.getDescripcion() != null && !p.getDescripcion().equals("")) {
                q.setParameter("descripcion", "%" + p.getDescripcion() + "%");
            }
            //Parametro precio en query
            if (precioInferior.equals(BigDecimal.ZERO) && precioSuperior.equals(BigDecimal.ZERO)) {
            } else if (!precioInferior.equals(BigDecimal.ZERO) && !precioSuperior.equals(BigDecimal.ZERO)) {
                q.setParameter("precioInferior", precioInferior);
                q.setParameter("precioSuperior", precioSuperior);
            } else if (precioInferior.equals(BigDecimal.ZERO) && !precioSuperior.equals(BigDecimal.ZERO)) {
                q.setParameter("precioSuperior", precioSuperior);
            } else if (!precioInferior.equals(BigDecimal.ZERO) && precioSuperior.equals(BigDecimal.ZERO)) {
                q.setParameter("precioInferior", precioInferior);
            }

            if (p.getIdCategoria() != null) {
                q.setParameter("idCategoria", p.getIdCategoria());
            }

            return q.getResultList();
        } finally {
            em.close();
        }
    }

        /**
     * Crea en base de datos un registro para el objeto Producto
     * @param producto identificador del producto a crear
     */
    public void create(Producto producto) throws PreexistingEntityException, Exception {
        throw new UnsupportedOperationException("Metodo no implementado");
    }

    /**
     * Edita en base de datos un registro para el objeto Producto
     * @param prodcuto identificador del producto a editar
     */
    public void edit(Producto producto) throws NonexistentEntityException, Exception {
        throw new UnsupportedOperationException("Metodo no implementado");
    }

    /**
     * Borra en base de datos un registro para el objeto Producto
     * @param id identificador del producto a borrar
     */
    public void destroy(Long id) throws NonexistentEntityException {
        throw new UnsupportedOperationException("Metodo no implementado");
    }
}
